﻿using System;

namespace ConsoleDemo.Polymorphism
{
    /// <summary>
    /// 接口解耦
    /// </summary>
    internal class Decoupling
    {
        //以老式手机举例，对用户来说他只关心手机可以接（打）电话和收（发）短信。
        //对于手机厂商，接口约束了他只要造的是手机，就必须可靠实现上面的四个功能。

        //用户如果丢了个手机，他只要再买个手机，不必关心是那个牌子的，肯定也包含这四个功能，上手就可以用。用术语来说就是“人和手机是解耦的”。
        public static void Call()
        {
            var user = new PhoneUser(new EricssonPhone());
            user.UsePhone();
        }

    }

    interface IPhone
    {
        void Dail();
        void PickUp();
        void Send();
        void Receive();
    }

    class PhoneUser
    {
        private IPhone _phone;

        public PhoneUser(IPhone phone)
        {
            _phone = phone;
        }

        public void UsePhone()
        {
            _phone.Dail();
            _phone.PickUp();
            _phone.Receive();
            _phone.Send();
        }
    }

    class NokiaPhone : IPhone
    {
        public void Dail()
        {
            Console.WriteLine("Nokia calling ...");
        }

        public void PickUp()
        {
            Console.WriteLine("Hello! This is Tim!");
        }

        public void Receive()
        {
            Console.WriteLine("Nokia message ring ...");
        }

        public void Send()
        {
            Console.WriteLine("Hello!");
        }
    }

    class EricssonPhone : IPhone
    {
        public void Dail()
        {
            Console.WriteLine("Ericsson calling ...");
        }

        public void PickUp()
        {
            Console.WriteLine("Hello! This is Tim!");
        }

        public void Send()
        {
            Console.WriteLine("Ericsson ring ...");
        }

        public void Receive()
        {
            Console.WriteLine("Good evening!");
        }
    }

    //没有用接口时，如果一个类坏了，你需要 Open 它再去修改，修改时可能产生难以预料的副作用。引入接口后，耦合度大幅降低，换手机只需要换个类名，就可以了。

    //等学了反射后，连这里的一行代码都不需要改，只要在配置文件中修改一个名字即可。

    //在代码中只要有可以替换的地方，就一定有接口的存在；接口就是为了解耦（松耦合）而生。

    //松耦合最大的好处就是让功能的提供方变得可替换，从而降低紧耦合时“功能的提供方不可替换”带来的高风险和高成本。
    //● 高风险：功能提供方一旦出问题，依赖于它的功能都挂
    //● 高成本：如果功能提供方的程序员崩了，会导致功能使用方的整个团队工作受阻
}
